package com.demo01_video.uitl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class FfmpegUtil {

    public boolean convertVideo(File inputFile, File outputFile) {
        try {
            // 构建 FFmpeg 命令
            List<String> command = new ArrayList<>();
            command.add("ffmpeg");
            command.add("-i");
            command.add(inputFile.getAbsolutePath()); // 输入文件
            command.add("-c:v");
            command.add("libx264"); // 视频编码器
            command.add("-preset");
            command.add("fast"); // 编码速度与压缩比的平衡
            command.add("-crf");
            command.add("23"); // 视频质量 (0-51, 越低质量越好)
            command.add("-c:a");
            command.add("aac"); // 音频编码器
            command.add("-b:a");
            command.add("128k"); // 音频比特率
            command.add("-movflags");
            command.add("+faststart"); // 优化网络播放
            command.add("-y"); // 覆盖输出文件
            command.add(outputFile.getAbsolutePath()); // 输出文件

            // 执行命令
            ProcessBuilder processBuilder = new ProcessBuilder(command);
            Process process = processBuilder.start();

            // 捕获输出流和错误流（防止缓冲区满导致进程阻塞）
            StreamGobbler outputGobbler = new StreamGobbler(process.getInputStream(), "OUTPUT");
            StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");
            outputGobbler.start();
            errorGobbler.start();

            // 等待进程完成
            int exitCode = process.waitFor();

            // 检查执行结果
            if (exitCode == 0) {
                log.info("视频转码成功: {} -> {}", inputFile.getName(), outputFile.getName());
                return true;
            } else {
                log.error("视频转码失败，退出码: {}", exitCode);
                return false;
            }
        } catch (IOException | InterruptedException e) {
            log.error("执行FFmpeg命令时发生异常", e);
            return false;
        }
    }

    // 用于异步处理FFmpeg输出的内部类
    private static class StreamGobbler extends Thread {
        InputStream is;
        String type;

        StreamGobbler(InputStream is, String type) {
            this.is = is;
            this.type = type;
        }

        @Override
        public void run() {
            try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
                String line;
                while ((line = br.readLine()) != null) {
                    if ("ERROR".equals(type)) {
                        log.error("FFmpeg {}: {}", type, line);
                    } else {
                        log.info("FFmpeg {}: {}", type, line);
                    }
                }
            } catch (IOException e) {
                log.error("读取FFmpeg输出流时发生异常", e);
            }
        }
    }
}
